<?php
App::uses('AppController', 'Controller');
/**
 * Users Controller
 *
 * @property User $User
 * @property PaginatorComponent $Paginator
 */
App::import('Vendor', 'Sycamore', array('file'=>'OAuthPHP-master'.DS.'src'.DS.'SycamorePHP'.DS.'sycamore.php'));

class UsersController extends AppController {

/**
 * Components
 *
 * @var array
 */
	public $components = array('Paginator', 'Cookie', 'Session');

/**
 * beforeFilter method
 **/
    public function beforeFilter()
    {
        parent::beforeFilter();
        $this->Cookie->name = 'ptsignup';
        $this->Cookie->key = Configure::read('ptsignup.cookie_key');
        $url = str_replace('http://', '', Configure::read('ptsignup.url'));
        # Note that PHP doesn't like 'localhost' as the domain
        $this->Cookie->domain = ($url == 'localhost' ? false : $url);
        $this->Cookie->path = Configure::read('ptsignup.path');
            #Configure::read('ptsignup.url').'/'.Configure::read('ptsignup.path');
        $this->Cookie->time = 3600*24*365; // approx 1 year
        $this->Cookie->httpOnly = true;
    }
    # This is only for testing purposes to get cookies working in cakePHP
    public function writecookie() {
        $this->Cookie->write('foo', array('xyz'=>3, 'wvu'=>'wwww'));
        $this->Session->setFlash("key=".Configure::read('ptsignup.cookie_key').", url=".Configure::read('ptsignup.url').', path='.Configure::read('ptsignup.path'));
        #$this->render("/Pages/home");
        return "HELLO";
    }
    # This is only for testing purposes to get cookies working in cakePHP
    public function readcookie() {
        $foo = $this->Cookie->read('ptsignup');
        #$foo = 'abc';
        #$this->Session->setFlash("HELLO foo=<pre>".print_r($foo,true)."</pre><br />\n");
        $this->set('foo', $foo);
        #$this->render("/Pages/home");
        #return "HELLO foo=<pre>".print_r($foo,true)."</pre><br />\n";
    }
/**
 * index method
 *
 * @return void
 */
	public function index() {
		$this->User->recursive = 0;
		$this->set('users', $this->Paginator->paginate());
	}

/**
 * view method
 *
 * @throws NotFoundException
 * @param string $id
 * @return void
 */
	public function view($id = null) {
		if (!$this->User->exists($id)) {
			throw new NotFoundException(__('Invalid user'));
		}
		$options = array('conditions' => array('User.' . $this->User->primaryKey => $id));
		$this->set('user', $this->User->find('first', $options));
	}

/**
 * add method
 *
 * @return void
 */
	public function add() {
		if ($this->request->is('post')) {
			$this->User->create();
			if ($this->User->save($this->request->data)) {
				$this->Session->setFlash(__('The user has been saved.'));
				return $this->redirect(array('action' => 'index'));
			} else {
				$this->Session->setFlash(__('The user could not be saved. Please, try again.'));
			}
		}
		$schools = $this->User->School->find('list');
		$families = $this->User->Family->find('list');
		$locations = $this->User->Location->find('list');
		$this->set(compact('schools', 'families', 'locations'));
	}

/**
 * edit method
 *
 * @throws NotFoundException
 * @param string $id
 * @return void
 */
	public function edit($id = null) {
		if (!$this->User->exists($id)) {
			throw new NotFoundException(__('Invalid user'));
		}
		if ($this->request->is(array('post', 'put'))) {
			if ($this->User->save($this->request->data)) {
				$this->Session->setFlash(__('The user has been saved.'));
				return $this->redirect(array('action' => 'index'));
			} else {
				$this->Session->setFlash(__('The user could not be saved. Please, try again.'));
			}
		} else {
			$options = array('conditions' => array('User.' . $this->User->primaryKey => $id));
			$this->request->data = $this->User->find('first', $options);
		}
		$schools = $this->User->School->find('list');
		$families = $this->User->Family->find('list');
		$locations = $this->User->Location->find('list');
		$this->set(compact('schools', 'families', 'locations'));
	}

/**
 * delete method
 *
 * @throws NotFoundException
 * @param string $id
 * @return void
 */
	public function delete($id = null) {
		$this->User->id = $id;
		if (!$this->User->exists()) {
			throw new NotFoundException(__('Invalid user'));
		}
		$this->request->allowMethod('post', 'delete');
		if ($this->User->delete()) {
			$this->Session->setFlash(__('The user has been deleted.'));
		} else {
			$this->Session->setFlash(__('The user could not be deleted. Please, try again.'));
		}
		return $this->redirect(array('action' => 'index'));
	}

    private function _getandsaveme($token) {
        $client_id = Configure::read('ptsignup.client_id');
        $client_secret = Configure::read('ptsignup.client_secret');
        $client = new OAuth2\Sycamore($client_id, $client_secret);

        //set the access token for this instance from the token stored in the cookie
        $client->setAccessToken($token);

        //grab my personal details
        $me = $client->fetch("/Me");

        if ($me) {
            $this->Cookie->write('me', $me['result']);
            echo "DEBUG: Wrote cookie ptsignup.me with <pre>".print_r($me['result'],true)."</pre>\n";
            if (!$user = $this->User->findById($me['result']['UserID'])) {
                $user = array('User' => array(
                    'id' => $me['result']['UserID'],
                    'school_id' => $me['result']['SchoolID'],
                    'family_id' => $me['result']['FamilyID'],
                    'fname' => $me['result']['FirstName'],
                    'lname' => $me['result']['LastName'],
                    'display_name' => $me['result']['FirstName'].' '.$me['result']['LastName'],
                    'email' => $me['result']['Email'],
                    'is_teacher' => ($me['result']['FamilyID']?0:1),
                    'superuser' => $me['result']['SuperUser'],
                    'signup_admin' => $me['result']['SuperUser'],
                ));
                if (!$this->User->save($user))
                    $user = false;
            }
            return $user;
        }
        return false;
    }

    public function logout() {
        $this->Cookie->delete('auth_token');
        $this->Cookie->delete('me');
        $this->Auth->logout();
    }
    public function login() {
        //if already logged-in, redirect
        if($this->Session->check('Auth.User')){
            $this->redirect($this->Auth->redirectUrl());      
        }

        #echo "DEBUG: Logging in within UsersController.<br />\n";
        $client_id = Configure::read('ptsignup.client_id');
        $client_secret = Configure::read('ptsignup.client_secret');
        #echo "DEBUG: Checking cookie<br />\n";
        #$debug = $this->Cookie->read('ptsignup');
        #echo "DEBUG: ptsignup cookie = <pre>".print_r($debug,true)."</pre><br />\n";
        if ($user = $this->Cookie->read('me.UserID')) {
            #echo "DEBUG: Goot cookie: $user<br />\n";
            if ($user = $this->User->findById($user)) {
                #echo "DEBUG: Found user rec: <pre>".print_r($user,true)."</pre><br />\n";
                $this->Auth->login($user);
                #die("DEBUG: WOULD HAVE RETURNED<br />\n");
                return $user;
            }
        } else {
            // maybe we have an auth_token?
            #echo "DEBUG: Checking for cookie auth_token<br />\n";
            if ($authtoken = $this->Cookie->read('auth_token')) {
                #echo "DEBUG: Found cookie auth_token=$authtoken<br />\n";
                if ($user = $this->_getandsaveme($authtoken)) {
                    #echo "DEBUG: Found user rec from authtoken: <pre>".print_r($user,true)."</pre><br />\n";
                    $this->Auth->login($user);
                    #die("DEBUG: WOULD HAVE RETURNED after auth login<br />\n");
                    return $user;
                }
            }
            #die("DEBUG: Would have gone on and redirected to Sycamore<br />\n");

            # OK, we got nothin. Go ahead and redirect to Sycamore to get the token.
            #$this->Session->setFlash(__('Would have redirected'));
            $client = new OAuth2\Sycamore($client_id, $client_secret);
            $authorization_endpoint = Configure::read('ptsignup.syc_authorization_endpoint');
            $redirect_uri = Configure::read('ptsignup.syc_redirect_uri');
            $scope = Configure::read('ptsignup.syc_scope');
            $auth_url = $client->getAuthenticationUrl($authorization_endpoint, $redirect_uri, $scope);
            #$this->Session->setFlash(__('Redirect url='.$auth_url));
            $this->redirect($auth_url);
        }
    }

    # In the oauth2 dance, this function is called when Sycamore passes back the auth_token as $_GET['code']
    public function receivetoken() {
        if (!$code = $this->request->query['code']) {
            #die("DEBUG: request=<pre>".print_r($this->request,true)."</pre><br />\n");
            $this->redirect(array('controller'=>'pages', 'action'=>'error'));
        }
        $dbg = "request=<pre>".print_r($this->request,true)."</pre>";
        #die("DEBUG: code=$code<br />\n");

        $client_id = Configure::read('ptsignup.client_id');
        $client_secret = Configure::read('ptsignup.client_secret');
        $token_endpoint = Configure::read('ptsignup.syc_token_endpoint');
        $redirect_uri = Configure::read('ptsignup.syc_redirect_uri');
        $params = array('code' => $code, 'redirect_uri' => $redirect_uri);

        //trade auth code for access token
        $client = new OAuth2\Sycamore($client_id, $client_secret);
        $response = $client->getAccessToken($token_endpoint, 'authorization_code', $params);
        #die("DEBUG: params=<pre>".print_r($params,true)."</pre>,response=<pre>".print_r($response,true)."</pre><br />\n");

        //returns json_decoded array with top level "result" array
        if ($token = $response["result"]["access_token"]) {

            //store access token in cookie for use later
            $this->Cookie->write("auth_token", $token);
            #echo "DEBUG: Wrote cookie ptsignup.auth_token with $token\n";

            if ($user = $this->_getandsaveme($token)) {
                $this->Auth->login($user);
                #$this->Session->setFlash('Would have redirected to a working page');
                $this->redirect($this->Auth->redirectUrl());      
            }
        } else {
            $this->Session->setFlash('ERROR: Unable to obtain authorization from server'
                .'DEBUG: code=$code, response=<pre>'.print_r($response,true).'</pre>'
                .', params=<pre>'.print_r($params,true).'</pre>'
                .', '.$dbg
            );
            $this->redirect(array('controller'=>'pages', 'action'=>'error'));
        }
    }
}
